package uplb.ics.cs190.e2d.time;

public class StandardTimer implements SystemTimer {

	protected int fps = 50;
	protected long delay;
	
	protected long start;
	protected long end;
	protected long timeDiff;
	protected long sleepTime;
	
	protected long overSleepTime;
	
	protected boolean isRunning;
	protected FPSCounter fpsCounter;

	public StandardTimer() {
		this.fpsCounter = new FPSCounter();
	}
	
	@Override
	public void start() {
		if(this.isRunning) {
			this.stop();
		}
		this.isRunning = true;
		
		this.delay = 1000 / this.fps;
		this.refresh();
		
		this.fpsCounter.refresh();
	}

	@Override
	public void stop() {
		this.isRunning = false;
	}

	@Override
	public long sleep() {
		this.end = System.currentTimeMillis();
		
		this.timeDiff = this.end - this.start;
		this.sleepTime = (this.delay - this.timeDiff) - this.overSleepTime;
		
		if(this.sleepTime > 0) {
			try {
				Thread.sleep(this.sleepTime);
			} catch(InterruptedException e) {
				
			}
			
			this.overSleepTime = (System.currentTimeMillis() - this.end) - this.sleepTime;
		} else {
			try {
				Thread.sleep(1);
			} catch(InterruptedException e) {
				
			}
			
			this.overSleepTime = 0;
		}
		
		this.fpsCounter.calculateFPS();
		
		long end = System.currentTimeMillis();
		long elapsedTime = end - this.start;
		this.start = end;
		
		return elapsedTime;
	}

	@Override
	public long getTime() {
		return System.currentTimeMillis();
	}

	@Override
	public void refresh() {
		this.start = System.currentTimeMillis();
		this.overSleepTime = 0;
	}

	@Override
	public boolean isRunning() {
		return this.isRunning;
	}

	@Override
	public int getCurrentFPS() {
		return this.fpsCounter.getFPS();
	}

	@Override
	public int getFPS() {
		return this.fps;
	}

	@Override
	public void setFPS(int fps) {
		if(this.fps != fps) {
			this.fps = fps;
			
			if(this.isRunning) {
				this.start();
			}
		}
	}

}